/*
 * 英才汇硕信息科技有限公司 拥有本软件版权 2021 并保留所有权利。
 * Copyright 2021, YCHS Information&Science Techology Co.,Ltd,
 * All right reserved.
 */
package com.ychs.lawyerback.service.impl;

import com.ychs.lawyerback.common.R;
import com.ychs.lawyerback.common.ResultCode;
import com.ychs.lawyerback.dto.LawyerOptDTO;
import com.ychs.lawyerback.dto.LawyerQueryDTO;
import com.ychs.lawyerback.dto.UserOptDTO;
import com.ychs.lawyerback.exception.BussinessException;
import com.ychs.lawyerback.mapper.DocumentMapper;
import com.ychs.lawyerback.mapper.LawyerCertificateMapper;
import com.ychs.lawyerback.mapper.LawyerMapper;
import com.ychs.lawyerback.mapper.UserMapper;
import com.ychs.lawyerback.pojo.DocumentEntity;
import com.ychs.lawyerback.pojo.LawyerCertificateEntity;
import com.ychs.lawyerback.pojo.LawyerEntity;
import com.ychs.lawyerback.pojo.UserEntity;
import com.ychs.lawyerback.service.DocumentService;
import com.ychs.lawyerback.service.LawyerService;
import com.ychs.lawyerback.service.UserService;
import com.ychs.lawyerback.vo.LawyerQueryVo;
import com.ychs.lawyerback.vo.LoginUserVo;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;



/**
 * @author mayujing
 * @version 1.0
 */
@Service
@Slf4j
public class LawyerServiceImpl implements LawyerService {


    @Autowired
    private LawyerCertificateMapper certificateMapper;

    @Autowired
    private DocumentService documentService;

    @Autowired
    private DocumentMapper documentMapper;

    @Autowired
    private LawyerMapper lawyerMapper;
    @Autowired
    private UserMapper userMapper;



    @Value("${file.upload-dir}")
    private String uploadDir;

    @Override
    public Map<String, Object> getLawyersByCondition(LawyerQueryDTO lawyerQueryDTO) {

        List<LawyerQueryVo> lawyers = lawyerMapper.getLawyersByCondition(lawyerQueryDTO);
        int total = lawyerMapper.getCountByCondition(lawyerQueryDTO);
        Map<String, Object> map = new HashMap<>();
        map.put("list", lawyers);
        map.put("total", total);
        return map;
    }



    @Override
    public LawyerQueryVo getLawyersByCondition(Long lawyerId) {
        // 1. 查询律师基本信息及单文件URL
        LawyerQueryVo lawyerVo = lawyerMapper.selectBaseInfoById(lawyerId);
        if (lawyerVo == null) {
            throw new BussinessException(ResultCode.DATA_NOT_FOUND);
        }

        // 2. 查询多证书列表
        List<LawyerCertificateEntity> certificates = certificateMapper.selectByLawyerId(lawyerId);
        lawyerVo.setCertificates(certificates);

        return lawyerVo;
        
    }

    @Override
    public LawyerQueryVo getByUserId(Long userId) {
        if (userId == null) {
            throw new BussinessException(ResultCode.PARAM_ERROR);
        }
        return lawyerMapper.selectByUserId(userId);
    }


    @Override
    @Transactional
    public Long addLawyer(LawyerOptDTO lawyerOptDTO) throws IOException {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        LoginUserVo loginUser = (LoginUserVo) request.getAttribute("loginUserVo");
        Long userId = loginUser.getId(); // 登录用户的ID

        /**
         * 1. 校验部分
         */
           //校验兼职律师
        checkPartTimeWork(lawyerOptDTO.getLawyerType(), lawyerOptDTO.getPartTimeWork());
           //校验身份证号是否已经存在
        if (lawyerMapper.countByIdCard(lawyerOptDTO.getIdCard()) > 0) {
            throw new BussinessException(ResultCode.LAWYER_IDCARD);
        }
           //校验执业证号是否存在
        if (lawyerMapper.countByLicenseNo(lawyerOptDTO.getLicenseNo())>0) {
            throw new BussinessException(ResultCode.LAWYER_LICENSE_NO);
        }

        /**
         * 3. 新增律师记录，并关联用户ID
         */
        //DTO转Entity
        LawyerEntity lawyerEntity = new LawyerEntity();
        BeanUtils.copyProperties(lawyerOptDTO, lawyerEntity);
        lawyerEntity.setId(userId); // 关联登录的用户id
        lawyerEntity.setCreateTime(new Date());
        lawyerEntity.setUpdateTime(new Date());

        //保存律师信息到数据库
        lawyerMapper.addLawyer(lawyerEntity);
        //获取自动生成的律师ID（用于后续文件关联）
        Long lawyerId = lawyerEntity.getLawyerId();

        // 校验律师ID是否生成成功
        if (lawyerId == null || lawyerId <= 0) {
            throw new BussinessException(ResultCode.DATA_INSERT_FAIL);
        }

        /**
         * 文件处理
         */
        // 1. 处理单文件：转所记录
        if (lawyerOptDTO.getTransferRecordsFile() != null && !lawyerOptDTO.getTransferRecordsFile().isEmpty()) {
            String transferUrl = documentService.uploadSingleFile(lawyerId,
                    lawyerOptDTO.getTransferRecordsFile(), 6 // 转所记录文件类型
            );
            // 更新律师表中的单文件URL
            lawyerMapper.updateFileUrl(lawyerId, "transferRecords", transferUrl);
        }

        //2.处理单文件：档案调转记录
        if (lawyerOptDTO.getFileTransferRecordsFile() != null && !lawyerOptDTO.getFileTransferRecordsFile().isEmpty()) {
            String fileTransferUrl = documentService.uploadSingleFile(lawyerId,
                    lawyerOptDTO.getFileTransferRecordsFile(),7
            );
            lawyerMapper.updateFileUrl(lawyerId, "fileTransferRecords", fileTransferUrl);
        }

        // 3.处理照片文件
        if (lawyerOptDTO.getPhotoFile() != null && !lawyerOptDTO.getPhotoFile().isEmpty()) {
            String photoUrl = documentService.uploadSingleFile(lawyerId,
                    lawyerOptDTO.getPhotoFile(), 9); // 假设9为照片文件类型
            lawyerMapper.updateFileUrl(lawyerId, "photo", photoUrl);
        }

        //5.多文件处理：证书
        List<MultipartFile> certFiles = lawyerOptDTO.getCertificateFiles();// 证书文件列表
        List<String> certNames = lawyerOptDTO.getCertificateNames();// 证书名称列表

        // 校验文件和名称数量是否匹配
        if (certFiles != null && !certFiles.isEmpty() && certNames != null && certNames.size() == certFiles.size()) {
            for (int i = 0; i < certFiles.size(); i++) {
                //第i个文件
                MultipartFile file = certFiles.get(i);
                //空文件则跳过
                if (file.isEmpty()) {
                    continue;
                }
                //上传文件并获取URL
                String certUrl = documentService.uploadSingleFile(lawyerId, file, 8);
                //保存证书相关信息
                // 2. 插入证书记录到数据库
                LawyerCertificateEntity certificateEntity = new LawyerCertificateEntity();
                certificateEntity.setLawyerId(lawyerId);// 关联律师ID
                certificateEntity.setCertificateName(certNames.get(i));// 证书名称
                certificateEntity.setCertificateUrl(certUrl);// 证书文件URL
                certificateMapper.insert(certificateEntity);// 插入数据库
            }
        }
        return userId;
    }





    @Override
    @Transactional
    public int editLawyer(LawyerOptDTO lawyerOptDTO) throws IOException {
        // 1. 校验律师是否存在
        LawyerEntity exist = lawyerMapper.getLawyerById(lawyerOptDTO.getLawyerId());
        if (exist == null) {
            throw new BussinessException(ResultCode.LAWYER_NOT_EXIST);
        }

        // 2. 其他校验逻辑（兼职、身份证号等）
        checkPartTimeWork(lawyerOptDTO.getLawyerType(), lawyerOptDTO.getPartTimeWork());
        if (!exist.getIdCard().equals(lawyerOptDTO.getIdCard()) && existsByIdCard(lawyerOptDTO.getIdCard())) {
            throw new BussinessException(ResultCode.LAWYER_IDCARD);
        }
        if (!exist.getLicenseNo().equals(lawyerOptDTO.getLicenseNo()) && existsByLicenseNo(lawyerOptDTO.getLicenseNo())) {
            throw new BussinessException(ResultCode.LAWYER_LICENSE_NO);
        }

        // 3. 复制基本属性
        LawyerEntity lawyerEntity = new LawyerEntity();
        BeanUtils.copyProperties(lawyerOptDTO, lawyerEntity);
        lawyerEntity.setUpdateBy(exist.getCreateBy());
        lawyerEntity.setUpdateTime(new Date());

        // 4. 处理文件更新（重点补充）
        Long lawyerId = lawyerOptDTO.getLawyerId();

        // 处理照片文件
        if (lawyerOptDTO.getPhotoFile() != null && !lawyerOptDTO.getPhotoFile().isEmpty()) {
            String photoUrl = documentService.uploadSingleFile(lawyerId,
                    lawyerOptDTO.getPhotoFile(), 9); // 照片文件类型
            lawyerMapper.updateFileUrl(lawyerId, "photo", photoUrl);
        }

        // 处理转所记录文件
        if (lawyerOptDTO.getTransferRecordsFile() != null && !lawyerOptDTO.getTransferRecordsFile().isEmpty()) {
            String transferUrl = documentService.uploadSingleFile(lawyerId,
                    lawyerOptDTO.getTransferRecordsFile(), 6); // 转所记录类型
            lawyerMapper.updateFileUrl(lawyerId, "transferRecords", transferUrl);
        }

        // 处理档案调转记录文件
        if (lawyerOptDTO.getFileTransferRecordsFile() != null && !lawyerOptDTO.getFileTransferRecordsFile().isEmpty()) {
            String fileTransferUrl = documentService.uploadSingleFile(lawyerId,
                    lawyerOptDTO.getFileTransferRecordsFile(), 7); // 档案调转类型
            lawyerMapper.updateFileUrl(lawyerId, "fileTransferRecords", fileTransferUrl);
        }

        // 1. 处理需要删除的特定证书
        List<Long> deleteCertIds = lawyerOptDTO.getDeleteCertificateIds();
        if (deleteCertIds != null && !deleteCertIds.isEmpty()) {
            // 查询要删除的证书详情（包含文件URL）
            List<LawyerCertificateEntity> deleteCerts = certificateMapper.selectByIds(deleteCertIds);

            // 逐个删除
            for (LawyerCertificateEntity cert : deleteCerts) {
                // 验证证书属于当前律师（防止越权删除）
                if (cert.getLawyerId().equals(lawyerId)) {
                    // 删除服务器上的文件
                    deleteFile(cert.getCertificateUrl());

                    // 删除document表中对应的记录（假设8是证书类型）
                    documentMapper.deleteByFileNameAndType(cert.getCertificateUrl(), 8);
                    // 从证书表中删除
                    certificateMapper.deleteById(cert.getId());
                }
            }
        }


        // 5. 处理证书文件（多文件）
        List<MultipartFile> certFiles = lawyerOptDTO.getCertificateFiles();
        List<String> certNames = lawyerOptDTO.getCertificateNames();
        if (certFiles != null && !certFiles.isEmpty() && certNames != null && certNames.size() == certFiles.size()) {

            // 新增新证书
            for (int i = 0; i < certFiles.size(); i++) {
                MultipartFile file = certFiles.get(i);
                if (file.isEmpty()) {
                    continue;
                }

                String certUrl = documentService.uploadSingleFile(lawyerId, file, 8);
                LawyerCertificateEntity cert = new LawyerCertificateEntity();
                cert.setLawyerId(lawyerId);
                cert.setCertificateName(certNames.get(i));
                cert.setCertificateUrl(certUrl);
                certificateMapper.insert(cert);
            }
        }

        // 6. 更新基本信息
        return lawyerMapper.editLawyer(lawyerEntity);
    }

    private void deleteFile(String certificateUrl) {
        if (certificateUrl == null || certificateUrl.isEmpty()) {
            return;
        }
        // 拼接完整文件路径（结合配置的上传根目录）
        String filePath = uploadDir + File.separator + certificateUrl;
        File file = new File(filePath);
        if (file.exists() && file.isFile()) {
            boolean deleted = file.delete();
            if (!deleted) {
                log.warn("文件删除失败: {}", filePath);
                throw new BussinessException(ResultCode.FILE_DELETE_ERROR);
            }
        }
    }


    @Override
    @Transactional
    public int deleteLawyer(List<Long> ids) {
        List<DocumentEntity> files = getFilesByLawyerIds(ids);
        for (DocumentEntity file : files) {
            //删除本地记录
            File localFile = new File(file.getFilePath());
            if (localFile.exists()) {
                boolean isDeleted = localFile.delete();
                if (!isDeleted) {
                    throw new BussinessException(ResultCode.FILE_DELETE_FAIL);
                }
            }
            documentMapper.deleteById(file.getId());
        }

        return lawyerMapper.deleteLawyer(ids);
    }

    @Override
    public List<DocumentEntity> getFilesByLawyerIds(List<Long> ids) {
        return documentMapper.selectByLawyerIds(ids);
    }


    private boolean existsByLicenseNo(String licenseNo) {
        return lawyerMapper.countByLicenseNo(licenseNo) > 0;
    }

    private boolean existsByIdCard(String idCard) {
        return lawyerMapper.countByIdCard(idCard) > 0;
    }


    private void checkPartTimeWork(String lawyerType, String partTimeWork) {
        // 兼职律师必须填写工作单位
        if ("兼职律师".equals(lawyerType) && (partTimeWork == null || partTimeWork.trim().isEmpty())) {
            throw new BussinessException(ResultCode.PART_TIME_WORK);
        }
        // 专职律师不能填写兼职工作单位
        if ("律师".equals(lawyerType) && partTimeWork != null && !partTimeWork.trim().isEmpty()) {
            throw new BussinessException(ResultCode.LAWYER_WORK);
        }
    }
}
